package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.heima.apis.article.IArticleClient;
import com.heima.common.aliyun.GreenImageScan;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.file.service.FileStorageService;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.wemedia.pojos.WmChannel;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.wemedia.mapper.WmChannelMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmUserMapper;
import com.heima.wemedia.service.WmNewsAutoScanService;
import jdk.nashorn.internal.ir.annotations.Ignore;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
@Transactional
public class WmNewsAutoScanServiceImpl implements WmNewsAutoScanService {
    @Autowired
    private WmNewsMapper wmNewsMapper;
    /**
     * 自媒体文章审核
     * @param id  自媒体文章id
     */
    @Override
    @Async  //标明当前方法是一个异步方法
    public void autoScanWmNews(Integer id) {
        log.info("开始文章审核");
        //1.查询自媒体文章
        WmNews wmNews = wmNewsMapper.selectById(id);
        if (wmNews == null){
            throw new RuntimeException("WmNewsAutoScanServiceImpl-文章不存在");
        }
        if (wmNews.getStatus().equals(WmNews.Status.SUBMIT.getCode())){
            log.info("文章状态为待审核状态");
            //2.内容中获取文本内容和图片
            Map<String,Object> textAndImages = handleTextAndImages(wmNews);
            //3.审核文本内容  阿里云接口
            boolean isTextScan = handleTextScan((String)textAndImages.get("content"),wmNews);
            if (!isTextScan){
                log.info("文本审核不通过");
                return;
            };
            //4.审核图片内容  阿里云接口
            boolean isImagesCan = handleImageScan((List<String>)textAndImages.get("images"),wmNews);
            if (!isImagesCan){
                log.info("图片审核不通过");
                return;
            };
            //5.审核成功之后,保存app端的相关文章数据 文章 文章配置 文章内容
            ResponseResult responseResult = saveAppArticle(wmNews);
            if (!responseResult.getCode().equals(200)){
                throw new RuntimeException("WmNewsAutoScanServiceImpl-文章审核，保存app端相关文章数据失败");
            }
            //6.回填article_id
            wmNews.setArticleId( (Long) responseResult.getData());

            //7.更新wmNews表中的数据,和设置状态码,返回审核结果
            updateWmNews(wmNews,WmNews.Status.PUBLISHED.getCode(),"文章审核通过");
        }else {
            log.info("文章不是待审核状态");
            return;
        }

    }

    @Autowired
    private WmChannelMapper wmChannelMapper;

    @Autowired
    private WmUserMapper wmUserMapper;

    //调用保存文章相关的方法
    @Autowired
    private IArticleClient articleClient;
    /**
     * 5.审核成功之后,保存app端的相关文章数据 文章 文章配置 文章内容
     * @param wmNews
     * @return
     */
    private ResponseResult saveAppArticle(WmNews wmNews) {
        log.info("保存文章开始{}",wmNews);
        //5.1 构造前端需要返回的数据
        ArticleDto dto = new ArticleDto();
        //5.2 属性拷贝
        BeanUtils.copyProperties(wmNews,dto);
        //5.3设置文章的布局
        dto.setLayout(wmNews.getType());
        //5.4 设置文章的频道 需要去频道表中去获取
        WmChannel wmChannel = wmChannelMapper.selectById(wmNews.getChannelId());
        if (wmChannel!= null){
            dto.setChannelName(wmChannel.getName());
        }
        //5.5 设置文章的作者和id 需要从user表中去获取
        WmUser wmUser = wmUserMapper.selectById(wmNews.getUserId());
        if (wmUser != null){
            dto.setAuthorName(wmUser.getName());
        }
        dto.setAuthorId(wmNews.getUserId().longValue());
        //5.6 设置文章的id
        if (wmNews.getArticleId() != null){
            dto.setId(wmNews.getArticleId());
        }
        //5.7 设置创建的时间
        dto.setCreatedTime(new Date());
        //5.8 保存文章相关的数据
        ResponseResult responseResult = articleClient.saveArticle(dto);
        return responseResult;

    }


    @Autowired
    private FileStorageService fileStorageService;

    @Autowired
    private GreenImageScan greenImageScan;
    /**
     * 4.审核图片内容  阿里云接口
     * 图片需要从minio里面下载下来审核
     * @param images
     * @param wmNews
     * @return
     */
    private boolean handleImageScan(List<String> images, WmNews wmNews) {
        boolean flag = true;
        //4.1如果没有照片,直接返回
        if (images == null && images.size() == 0){
            return flag;
        }
        //4.2 从minio里面下载照片
        //去重
        List<String> iamges = images.stream().distinct().collect(Collectors.toList());

        //4.3 新建一个list的byte的数组 用于存储下载来的照片
        ArrayList<byte[]> imagesList = new ArrayList<>();
        for (String iamge : iamges) {
            byte[] bytes = fileStorageService.downLoadFile(iamge);
            imagesList.add(bytes);
        }
        //4.4 审核照片
        try {
            Map imageScanMap = greenImageScan.imageScan(imagesList);
            if (imageScanMap != null){
                //审核失败
                if (imageScanMap.get("suggestion").equals("block")){
                    flag = false;
                    updateWmNews(wmNews,WmNews.Status.FAIL.getCode(),"当前图片存在违规内容");  //Status.FAIL.getCode()为审核失败
                }
                //图片有不确定信息 需要人工审核
                if (imageScanMap.get("suggestion").equals("review")) {
                    flag = false;
                    updateWmNews(wmNews,WmNews.Status.ADMIN_AUTH.getCode(),"当前文章中存在不确定的审核,需要人工审核");
                }
            }
        } catch (Exception e) {
            flag = false;
            e.printStackTrace();
        }
        return flag;
    }

    @Autowired
    private GreenTextScan greenTextScan;

    /**
     * 3.审核文本内容  阿里云接口
     * @param content
     * @param wmNews
     * @return
     */
    private boolean handleTextScan(String content, WmNews wmNews) {
        //3.1 定义一个标志
        boolean flag = true;
        try {
            //文章的标题也需要审核
            Map textScanMap = greenTextScan.greeTextScan(wmNews.getTitle() + "-" + content);
            if (textScanMap != null){
                //3.2审核失败
                if (textScanMap.get("suggestion").equals("block")){
                    flag = false;
                    updateWmNews(wmNews,WmNews.Status.FAIL.getCode(),"当前文章存在违规内容");  //Status.FAIL.getCode()为审核失败
                }
                //3.3不确定信息需要人工审核
                if (textScanMap.get("suggestion").equals("review")){
                    flag = false;
                    updateWmNews(wmNews,WmNews.Status.ADMIN_AUTH.getCode(),"当前文章中存在不确定的审核,需要人工审核");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            flag = false;
        }
        return flag;
    }

    /**
     * 上接第3步
     * 审核文本的时候,要修改文章的内容 不通过的原因以及审核的状态,原因
     * @param wmNews
     * @param status
     * @param reason
     */
    private void updateWmNews(WmNews wmNews, short status, String reason) {
        wmNews.setStatus(status);
        wmNews.setReason(reason);
        wmNewsMapper.updateById(wmNews);
    }

    /**
     * 2.内容中获取文本内容和图片
     * @param wmNews
     * @return
     */
    private Map<String, Object> handleTextAndImages(WmNews wmNews) {
        //定义一个stringBuilder用于存储纯文本内容
        StringBuilder stringBuilder = new StringBuilder();
        //定义一个list用于存储图片的信息
        ArrayList<String> images = new ArrayList<>();
        //2.1 从自媒体文章中获取文本或者图片
        if (!StringUtils.isEmpty(wmNews.getContent())){
            List<Map> maps = JSONArray.parseArray(wmNews.getContent(), Map.class);
            for (Map map : maps) {
                //如果是文本就保存到stringBuilder中去
                if (map.get("type").equals("text")){
                    stringBuilder.append(map.get("value"));
                }
                //如果是图片就保存到list中去
                if (map.get("type").equals("iamge")){
                    images.add((String)map.get("value"));
                }
            }
        }
        //2.2 从自媒体封面中获取图片
        if (StringUtils.isNotEmpty(wmNews.getImages())){
            String[] img = wmNews.getImages().split(",");
            images.addAll(Arrays.asList(img));
        }
        //2.3 返回封装的数据
        Map<String, Object> resulstMap = new HashMap<>();
        resulstMap.put("content",stringBuilder.toString());
        resulstMap.put("images",images);
        return resulstMap;
    }
}
